package mover;

import functions.*;

public class SimpleFunctionMover extends GameMover {	
	private double alpha = 0, var = 0;
	private double xVal = 0, yVal = 0;
	private int bounce = 1, xTmp = 0, yTmp = 0;
	private MoveFunction func;

	public SimpleFunctionMover(int xMove, int yMove, MoveFunction func) {
		this.xMove = xMove;
		this.yMove = yMove;
		this.func = func;

		this.alpha = calculateAlpha(yMove, xMove);
	}

	@Override
	public void move(int counter) {
		//timesaver
		if(xMove == 0 && yMove == 0) return;

		if(xMove != 0 && counter%xMove == 0) {
			var = func.getRealNextY() * bounce * yMult;

			//Koordinatentransformation
			xPos += signum(xMove) * xMult;
			xVal = (xPos * Math.cos(alpha)
					- (yPos + var) * Math.sin(alpha));
		}
		if(yMove != 0 && counter%yMove == 0) {
			//Koordinatentransformation
			yPos += signum(yMove) * yMult;
			yVal = (xPos * Math.sin(alpha)
					+ (yPos + var) * Math.cos(alpha));
		}

		//		if(xMove != 0 && counter%xMove == 0) {
		//			var = func.getRealNextY() * bounce;
		//
		//			//Koordinatentransformation
		//			xPos += signum(xMove) * xMult;
		//		}
		//		if(yMove != 0 && counter%yMove == 0) {
		//			//Koordinatentransformation
		//			yPos += signum(yMove) * yMult;
		//		}
	}

	@Override
	public void reset() {
		super.reset();
		func.reset();
	}

	@Override
	public int getXPos() {
		if(alpha == 0) return xPos;
		//		return (int) (xPos * Math.cos(alpha)
		//				- (yPos + var) * Math.sin(alpha));
		return (int) xVal + xTmp;
	}
	@Override
	public int getYPos() {
		if(alpha == 0) return (int) (yPos + var);
		//		return (int) (xPos * Math.sin(alpha)
		//				+ (yPos + var) * Math.cos(alpha));
		return (int) yVal + yTmp;
	}

	@Override
	public void bounce(boolean xAxis, int overlay) {
			super.bounce(xAxis, overlay);
			
			//Aktuelle Position wird zwischengespeichert, wird nun relativ dazu bewegt
			xTmp += (int) xVal;
			yTmp += (int) yVal;
			
			//Die anderen Werte werden reseted
			xPos = yPos = 0;
			xVal = yVal = 0;
			func.reset();

			//Das Element wird genau einen Pixel weit zurueck ins Bild gesetzt
			if(xAxis) {
				xTmp -= overlay;
			} else {
				yTmp -= overlay;
			}

			//Der Winkel wird umgekehrt ebenso wie die Funktionswerte
			alpha *= -1;
			bounce *= -1;
	}
	

	private double calculateAlpha(int x, int y) {
		double ret = 0;

		//Notwendig zur Achsenrotation / Koordinatentransformation
		if(x != 0 && y != 0)
			ret = Math.atan(((double) y) / x);
		// Sonderfall
		else if(x == 0)
			ret = Math.PI/2;

		return ret;
	}

	@Override
	public SimpleFunctionMover clone() throws CloneNotSupportedException {
		SimpleFunctionMover clone = new SimpleFunctionMover(this.xMove, this.yMove, this.func.clone());
		this.clone_help(clone);
		clone.alpha = this.alpha;
		clone.bounce = this.bounce;
		clone.var = this.var;
		clone.xTmp = this.xTmp;
		clone.xVal = this.xVal;
		clone.yTmp = this.yTmp;
		clone.yVal = this.yVal;
		
		return clone;
	}
}